/* Generated from 'MathContext.nrx' 8 Sep 2000 11:07:48 [v2.00] */
/* Options: Binary Comments Crossref Format Java Logo Strictargs Strictcase Trace2 Verbose3 */
//--package com.ibm.icu.math;
/* ------------------------------------------------------------------ */
/* MathContext -- Math context settings                               */
/* ------------------------------------------------------------------ */
/* Copyright IBM Corporation, 1997, 2000.  All Rights Reserved.       */
/*                                                                    */
/*   The MathContext object encapsulates the settings used by the     */
/*   BigDecimal class; it could also be used by other arithmetics.    */
/* ------------------------------------------------------------------ */
/* Notes:                                                             */
/*                                                                    */
/* 1. The properties are checked for validity on construction, so     */
/*    the BigDecimal class may assume that they are correct.          */
/* ------------------------------------------------------------------ */
/* Author:    Mike Cowlishaw                                          */
/* 1997.09.03 Initial version (edited from netrexx.lang.RexxSet)      */
/* 1997.09.12 Add lostDigits property                                 */
/* 1998.05.02 Make the class immutable and final; drop set methods    */
/* 1998.06.05 Add Round (rounding modes) property                     */
/* 1998.06.25 Rename from DecimalContext; allow digits=0              */
/* 1998.10.12 change to com.ibm.icu.math package                          */
/* 1999.02.06 add javadoc comments                                    */
/* 1999.03.05 simplify; changes from discussion with J. Bloch         */
/* 1999.03.13 1.00 release to IBM Centre for Java Technology          */
/* 1999.07.10 1.04 flag serialization unused                          */
/* 2000.01.01 1.06 copyright update                                   */
/* ------------------------------------------------------------------ */

/* JavaScript conversion (c) 2003 STZ-IDA and PTV AG, Karlsruhe, Germany */

/**
 * The <code>MathContext</code> immutable class encapsulates the settings
 * understood by the operator methods of the {@link BigDecimal} class (and
 * potentially other classes). Operator methods are those that effect an
 * operation on a number or a pair of numbers.
 * <p>
 * The settings, which are not base-dependent, comprise:
 * <ol>
 * <li><code>digits</code>: the number of digits (precision) to be used for
 * an operation
 * <li><code>form</code>: the form of any exponent that results from the
 * operation
 * <li><code>lostDigits</code>: whether checking for lost digits is enabled
 * <li><code>roundingMode</code>: the algorithm to be used for rounding.
 * </ol>
 * <p>
 * When provided, a <code>MathContext</code> object supplies the settings for
 * an operation directly.
 * <p>
 * When <code>MathContext.DEFAULT</code> is provided for a
 * <code>MathContext</code> parameter then the default settings are used (<code>9, SCIENTIFIC, false, ROUND_HALF_UP</code>).
 * <p>
 * In the <code>BigDecimal</code> class, all methods which accept a
 * <code>MathContext</code> object defaults) also have a version of the method
 * which does not accept a MathContext parameter. These versions carry out
 * unlimited precision fixed point arithmetic (as though the settings were (<code>0, PLAIN, false, ROUND_HALF_UP</code>).
 * <p>
 * The instance variables are shared with default access (so they are directly
 * accessible to the <code>BigDecimal</code> class), but must never be
 * changed.
 * <p>
 * The rounding mode constants have the same names and values as the constants
 * of the same name in <code>java.math.BigDecimal</code>, to maintain
 * compatibility with earlier versions of <code>BigDecimal</code>.
 * 
 * @see BigDecimal
 * @author Mike Cowlishaw
 * @stable ICU 2.0
 */

// --public final class MathContext implements java.io.Serializable{
// --private static final java.lang.String $0="MathContext.nrx";
// -- methods
MathContext.prototype.getDigits = getDigits;
MathContext.prototype.getForm = getForm;
MathContext.prototype.getLostDigits = getLostDigits;
MathContext.prototype.getRoundingMode = getRoundingMode;
MathContext.prototype.toString = toString;
MathContext.prototype.isValidRound = isValidRound;

/* ----- Properties ----- */
/* properties public constant */
/**
 * Plain (fixed point) notation, without any exponent. Used as a setting to
 * control the form of the result of a <code>BigDecimal</code> operation. A
 * zero result in plain form may have a decimal part of one or more zeros.
 * 
 * @see #ENGINEERING
 * @see #SCIENTIFIC
 * @stable ICU 2.0
 */
// --public static final int PLAIN=0; // [no exponent]
MathContext.prototype.PLAIN = 0; // [no exponent]

/**
 * Standard floating point notation (with scientific exponential format, where
 * there is one digit before any decimal point). Used as a setting to control
 * the form of the result of a <code>BigDecimal</code> operation. A zero
 * result in plain form may have a decimal part of one or more zeros.
 * 
 * @see #ENGINEERING
 * @see #PLAIN
 * @stable ICU 2.0
 */
// --public static final int SCIENTIFIC=1; // 1 digit before .
MathContext.prototype.SCIENTIFIC = 1; // 1 digit before .

/**
 * Standard floating point notation (with engineering exponential format, where
 * the power of ten is a multiple of 3). Used as a setting to control the form
 * of the result of a <code>BigDecimal</code> operation. A zero result in
 * plain form may have a decimal part of one or more zeros.
 * 
 * @see #PLAIN
 * @see #SCIENTIFIC
 * @stable ICU 2.0
 */
// --public static final int ENGINEERING=2; // 1-3 digits before .
MathContext.prototype.ENGINEERING = 2; // 1-3 digits before .

// The rounding modes match the original BigDecimal class values
/**
 * Rounding mode to round to a more positive number. Used as a setting to
 * control the rounding mode used during a <code>BigDecimal</code> operation.
 * <p>
 * If any of the discarded digits are non-zero then the result should be rounded
 * towards the next more positive digit.
 * 
 * @stable ICU 2.0
 */
// --public static final int ROUND_CEILING=2;
MathContext.prototype.ROUND_CEILING = 2;

/**
 * Rounding mode to round towards zero. Used as a setting to control the
 * rounding mode used during a <code>BigDecimal</code> operation.
 * <p>
 * All discarded digits are ignored (truncated). The result is neither
 * incremented nor decremented.
 * 
 * @stable ICU 2.0
 */
// --public static final int ROUND_DOWN=1;
MathContext.prototype.ROUND_DOWN = 1;

/**
 * Rounding mode to round to a more negative number. Used as a setting to
 * control the rounding mode used during a <code>BigDecimal</code> operation.
 * <p>
 * If any of the discarded digits are non-zero then the result should be rounded
 * towards the next more negative digit.
 * 
 * @stable ICU 2.0
 */
// --public static final int ROUND_FLOOR=3;
MathContext.prototype.ROUND_FLOOR = 3;

/**
 * Rounding mode to round to nearest neighbor, where an equidistant value is
 * rounded down. Used as a setting to control the rounding mode used during a
 * <code>BigDecimal</code> operation.
 * <p>
 * If the discarded digits represent greater than half (0.5 times) the value of
 * a one in the next position then the result should be rounded up (away from
 * zero). Otherwise the discarded digits are ignored.
 * 
 * @stable ICU 2.0
 */
// --public static final int ROUND_HALF_DOWN=5;
MathContext.prototype.ROUND_HALF_DOWN = 5;

/**
 * Rounding mode to round to nearest neighbor, where an equidistant value is
 * rounded to the nearest even neighbor. Used as a setting to control the
 * rounding mode used during a <code>BigDecimal</code> operation.
 * <p>
 * If the discarded digits represent greater than half (0.5 times) the value of
 * a one in the next position then the result should be rounded up (away from
 * zero). If they represent less than half, then the result should be rounded
 * down.
 * <p>
 * Otherwise (they represent exactly half) the result is rounded down if its
 * rightmost digit is even, or rounded up if its rightmost digit is odd (to make
 * an even digit).
 * 
 * @stable ICU 2.0
 */
// --public static final int ROUND_HALF_EVEN=6;
MathContext.prototype.ROUND_HALF_EVEN = 6;

/**
 * Rounding mode to round to nearest neighbor, where an equidistant value is
 * rounded up. Used as a setting to control the rounding mode used during a
 * <code>BigDecimal</code> operation.
 * <p>
 * If the discarded digits represent greater than or equal to half (0.5 times)
 * the value of a one in the next position then the result should be rounded up
 * (away from zero). Otherwise the discarded digits are ignored.
 * 
 * @stable ICU 2.0
 */
// --public static final int ROUND_HALF_UP=4;
MathContext.prototype.ROUND_HALF_UP = 4;

/**
 * Rounding mode to assert that no rounding is necessary. Used as a setting to
 * control the rounding mode used during a <code>BigDecimal</code> operation.
 * <p>
 * Rounding (potential loss of information) is not permitted. If any of the
 * discarded digits are non-zero then an <code>ArithmeticException</code>
 * should be thrown.
 * 
 * @stable ICU 2.0
 */
// --public static final int ROUND_UNNECESSARY=7;
MathContext.prototype.ROUND_UNNECESSARY = 7;

/**
 * Rounding mode to round away from zero. Used as a setting to control the
 * rounding mode used during a <code>BigDecimal</code> operation.
 * <p>
 * If any of the discarded digits are non-zero then the result will be rounded
 * up (away from zero).
 * 
 * @stable ICU 2.0
 */
// --public static final int ROUND_UP=0;
MathContext.prototype.ROUND_UP = 0;

/* properties shared */
/**
 * The number of digits (precision) to be used for an operation. A value of 0
 * indicates that unlimited precision (as many digits as are required) will be
 * used.
 * <p>
 * The {@link BigDecimal} operator methods use this value to determine the
 * precision of results. Note that leading zeros (in the integer part of a
 * number) are never significant.
 * <p>
 * <code>digits</code> will always be non-negative.
 * 
 * @serial
 */
// --int digits;
/**
 * The form of results from an operation.
 * <p>
 * The {@link BigDecimal} operator methods use this value to determine the form
 * of results, in particular whether and how exponential notation should be
 * used.
 * 
 * @see #ENGINEERING
 * @see #PLAIN
 * @see #SCIENTIFIC
 * @serial
 */
// --int form; // values for this must fit in a byte
/**
 * Controls whether lost digits checking is enabled for an operation. Set to
 * <code>true</code> to enable checking, or to <code>false</code> to disable
 * checking.
 * <p>
 * When enabled, the {@link BigDecimal} operator methods check the precision of
 * their operand or operands, and throw an <code>ArithmeticException</code> if
 * an operand is more precise than the digits setting (that is, digits would be
 * lost). When disabled, operands are rounded to the specified digits.
 * 
 * @serial
 */
// --boolean lostDigits;
/**
 * The rounding algorithm to be used for an operation.
 * <p>
 * The {@link BigDecimal} operator methods use this value to determine the
 * algorithm to be used when non-zero digits have to be discarded in order to
 * reduce the precision of a result. The value must be one of the public
 * constants whose name starts with <code>ROUND_</code>.
 * 
 * @see #ROUND_CEILING
 * @see #ROUND_DOWN
 * @see #ROUND_FLOOR
 * @see #ROUND_HALF_DOWN
 * @see #ROUND_HALF_EVEN
 * @see #ROUND_HALF_UP
 * @see #ROUND_UNNECESSARY
 * @see #ROUND_UP
 * @serial
 */
// --int roundingMode;
/* properties private constant */
// default settings
// --private static final int DEFAULT_FORM=SCIENTIFIC;
// --private static final int DEFAULT_DIGITS=9;
// --private static final boolean DEFAULT_LOSTDIGITS=false;
// --private static final int DEFAULT_ROUNDINGMODE=ROUND_HALF_UP;
MathContext.prototype.DEFAULT_FORM = MathContext.prototype.SCIENTIFIC;
MathContext.prototype.DEFAULT_DIGITS = 9;
MathContext.prototype.DEFAULT_LOSTDIGITS = false;
MathContext.prototype.DEFAULT_ROUNDINGMODE = MathContext.prototype.ROUND_HALF_UP;

/* properties private constant */

// --private static final int MIN_DIGITS=0; // smallest value for DIGITS.
// --private static final int MAX_DIGITS=999999999; // largest value for DIGITS.
// If increased,
MathContext.prototype.MIN_DIGITS = 0; // smallest value for DIGITS.
MathContext.prototype.MAX_DIGITS = 999999999; // largest value for DIGITS. If
// increased,
// the BigDecimal class may need update.
// list of valid rounding mode values, most common two first
// --private static final int ROUNDS[]=new
// int[]{ROUND_HALF_UP,ROUND_UNNECESSARY,ROUND_CEILING,ROUND_DOWN,ROUND_FLOOR,ROUND_HALF_DOWN,ROUND_HALF_EVEN,ROUND_UP};
MathContext.prototype.ROUNDS = new Array(MathContext.prototype.ROUND_HALF_UP,
		MathContext.prototype.ROUND_UNNECESSARY,
		MathContext.prototype.ROUND_CEILING, MathContext.prototype.ROUND_DOWN,
		MathContext.prototype.ROUND_FLOOR,
		MathContext.prototype.ROUND_HALF_DOWN,
		MathContext.prototype.ROUND_HALF_EVEN, MathContext.prototype.ROUND_UP);

// --private static final java.lang.String ROUNDWORDS[]=new
// java.lang.String[]{"ROUND_HALF_UP","ROUND_UNNECESSARY","ROUND_CEILING","ROUND_DOWN","ROUND_FLOOR","ROUND_HALF_DOWN","ROUND_HALF_EVEN","ROUND_UP"};
// // matching names of the ROUNDS values
MathContext.prototype.ROUNDWORDS = new Array("ROUND_HALF_UP",
		"ROUND_UNNECESSARY", "ROUND_CEILING", "ROUND_DOWN", "ROUND_FLOOR",
		"ROUND_HALF_DOWN", "ROUND_HALF_EVEN", "ROUND_UP"); // matching names of
// the ROUNDS values

/* properties private constant unused */

// Serialization version
// --private static final long serialVersionUID=7163376998892515376L;
/* properties public constant */
/**
 * A <code>MathContext</code> object initialized to the default settings for
 * general-purpose arithmetic. That is,
 * <code>digits=9 form=SCIENTIFIC lostDigits=false
 * roundingMode=ROUND_HALF_UP</code>.
 * 
 * @see #SCIENTIFIC
 * @see #ROUND_HALF_UP
 * @stable ICU 2.0
 */
// --public static final com.ibm.icu.math.MathContext DEFAULT=new
// com.ibm.icu.math.MathContext(DEFAULT_DIGITS,DEFAULT_FORM,DEFAULT_LOSTDIGITS,DEFAULT_ROUNDINGMODE);
MathContext.prototype.DEFAULT = new MathContext(
		MathContext.prototype.DEFAULT_DIGITS,
		MathContext.prototype.DEFAULT_FORM,
		MathContext.prototype.DEFAULT_LOSTDIGITS,
		MathContext.prototype.DEFAULT_ROUNDINGMODE);

/* ----- Constructors ----- */

/**
 * Constructs a new <code>MathContext</code> with a specified precision. The
 * other settings are set to the default values (see {@link #DEFAULT}).
 * 
 * An <code>IllegalArgumentException</code> is thrown if the
 * <code>setdigits</code> parameter is out of range (&lt;0 or &gt;999999999).
 * 
 * @param setdigits
 *            The <code>int</code> digits setting for this
 *            <code>MathContext</code>.
 * @throws IllegalArgumentException
 *             parameter out of range.
 * @stable ICU 2.0
 */

// --public MathContext(int setdigits){
// -- this(setdigits,DEFAULT_FORM,DEFAULT_LOSTDIGITS,DEFAULT_ROUNDINGMODE);
// -- return;}
/**
 * Constructs a new <code>MathContext</code> with a specified precision and
 * form. The other settings are set to the default values (see {@link #DEFAULT}).
 * 
 * An <code>IllegalArgumentException</code> is thrown if the
 * <code>setdigits</code> parameter is out of range (&lt;0 or &gt;999999999),
 * or if the value given for the <code>setform</code> parameter is not one of
 * the appropriate constants.
 * 
 * @param setdigits
 *            The <code>int</code> digits setting for this
 *            <code>MathContext</code>.
 * @param setform
 *            The <code>int</code> form setting for this
 *            <code>MathContext</code>.
 * @throws IllegalArgumentException
 *             parameter out of range.
 * @stable ICU 2.0
 */

// --public MathContext(int setdigits,int setform){
// -- this(setdigits,setform,DEFAULT_LOSTDIGITS,DEFAULT_ROUNDINGMODE);
// -- return;}
/**
 * Constructs a new <code>MathContext</code> with a specified precision, form,
 * and lostDigits setting. The roundingMode setting is set to its default value
 * (see {@link #DEFAULT}).
 * 
 * An <code>IllegalArgumentException</code> is thrown if the
 * <code>setdigits</code> parameter is out of range (&lt;0 or &gt;999999999),
 * or if the value given for the <code>setform</code> parameter is not one of
 * the appropriate constants.
 * 
 * @param setdigits
 *            The <code>int</code> digits setting for this
 *            <code>MathContext</code>.
 * @param setform
 *            The <code>int</code> form setting for this
 *            <code>MathContext</code>.
 * @param setlostdigits
 *            The <code>boolean</code> lostDigits setting for this
 *            <code>MathContext</code>.
 * @throws IllegalArgumentException
 *             parameter out of range.
 * @stable ICU 2.0
 */

// --public MathContext(int setdigits,int setform,boolean setlostdigits){
// -- this(setdigits,setform,setlostdigits,DEFAULT_ROUNDINGMODE);
// -- return;}
/**
 * Constructs a new <code>MathContext</code> with a specified precision, form,
 * lostDigits, and roundingMode setting.
 * 
 * An <code>IllegalArgumentException</code> is thrown if the
 * <code>setdigits</code> parameter is out of range (&lt;0 or &gt;999999999),
 * or if the value given for the <code>setform</code> or
 * <code>setroundingmode</code> parameters is not one of the appropriate
 * constants.
 * 
 * @param setdigits
 *            The <code>int</code> digits setting for this
 *            <code>MathContext</code>.
 * @param setform
 *            The <code>int</code> form setting for this
 *            <code>MathContext</code>.
 * @param setlostdigits
 *            The <code>boolean</code> lostDigits setting for this
 *            <code>MathContext</code>.
 * @param setroundingmode
 *            The <code>int</code> roundingMode setting for this
 *            <code>MathContext</code>.
 * @throws IllegalArgumentException
 *             parameter out of range.
 * @stable ICU 2.0
 */

// --public MathContext(int setdigits,int setform,boolean setlostdigits,int
// setroundingmode){super();
function MathContext() {
	// -- members
	this.digits = 0;
	this.form = 0; // values for this must fit in a byte
	this.lostDigits = false;
	this.roundingMode = 0;

	// -- overloaded ctor
	var setform = this.DEFAULT_FORM;
	var setlostdigits = this.DEFAULT_LOSTDIGITS;
	var setroundingmode = this.DEFAULT_ROUNDINGMODE;
	if (MathContext.arguments.length == 4) {
		setform = MathContext.arguments[1];
		setlostdigits = MathContext.arguments[2];
		setroundingmode = MathContext.arguments[3];
	} else if (MathContext.arguments.length == 3) {
		setform = MathContext.arguments[1];
		setlostdigits = MathContext.arguments[2];
	} else if (MathContext.arguments.length == 2) {
		setform = MathContext.arguments[1];
	} else if (MathContext.arguments.length != 1) {
		throw "MathContext(): " + MathContext.arguments.length
				+ " arguments given; expected 1 to 4"
	}
	var setdigits = MathContext.arguments[0];

	// set values, after checking
	if (setdigits != this.DEFAULT_DIGITS) {
		if (setdigits < this.MIN_DIGITS)
			throw "MathContext(): Digits too small: " + setdigits;
		if (setdigits > this.MAX_DIGITS)
			throw "MathContext(): Digits too large: " + setdigits;
	}
	{/* select */
		if (setform == this.SCIENTIFIC)
			; // [most common]
		else if (setform == this.ENGINEERING)
			;
		else if (setform == this.PLAIN)
			;
		else {
			throw "MathContext() Bad form value: " + setform;
		}
	}
	if ((!(this.isValidRound(setroundingmode))))
		throw "MathContext(): Bad roundingMode value: " + setroundingmode;
	this.digits = setdigits;
	this.form = setform;
	this.lostDigits = setlostdigits; // [no bad value possible]
	this.roundingMode = setroundingmode;
	return;
}

/**
 * Returns the digits setting. This value is always non-negative.
 * 
 * @return an <code>int</code> which is the value of the digits setting
 * @stable ICU 2.0
 */

// --public int getDigits(){
function getDigits() {
	return this.digits;
}

/**
 * Returns the form setting. This will be one of {@link #ENGINEERING},
 * {@link #PLAIN}, or {@link #SCIENTIFIC}.
 * 
 * @return an <code>int</code> which is the value of the form setting
 * @stable ICU 2.0
 */

// --public int getForm(){
function getForm() {
	return this.form;
}

/**
 * Returns the lostDigits setting. This will be either <code>true</code>
 * (enabled) or <code>false</code> (disabled).
 * 
 * @return a <code>boolean</code> which is the value of the lostDigits setting
 * @stable ICU 2.0
 */

// --public boolean getLostDigits(){
function getLostDigits() {
	return this.lostDigits;
}

/**
 * Returns the roundingMode setting. This will be one of {@link  #ROUND_CEILING},
 * {@link  #ROUND_DOWN}, {@link  #ROUND_FLOOR}, {@link  #ROUND_HALF_DOWN},
 * {@link  #ROUND_HALF_EVEN}, {@link  #ROUND_HALF_UP},
 * {@link  #ROUND_UNNECESSARY}, or {@link  #ROUND_UP}.
 * 
 * @return an <code>int</code> which is the value of the roundingMode setting
 * @stable ICU 2.0
 */

// --public int getRoundingMode(){
function getRoundingMode() {
	return this.roundingMode;
}

/**
 * Returns the <code>MathContext</code> as a readable string. The
 * <code>String</code> returned represents the settings of the
 * <code>MathContext</code> object as four blank-delimited words separated by
 * a single blank and with no leading or trailing blanks, as follows:
 * <ol>
 * <li> <code>digits=</code>, immediately followed by the value of the digits
 * setting as a numeric word.
 * <li> <code>form=</code>, immediately followed by the value of the form
 * setting as an uppercase word (one of <code>SCIENTIFIC</code>,
 * <code>PLAIN</code>, or <code>ENGINEERING</code>).
 * <li> <code>lostDigits=</code>, immediately followed by the value of the
 * lostDigits setting (<code>1</code> if enabled, <code>0</code> if
 * disabled).
 * <li> <code>roundingMode=</code>, immediately followed by the value of the
 * roundingMode setting as a word. This word will be the same as the name of the
 * corresponding public constant.
 * </ol>
 * <p>
 * For example: <br>
 * <code>
 * digits=9 form=SCIENTIFIC lostDigits=0 roundingMode=ROUND_HALF_UP
 * </code>
 * <p>
 * Additional words may be appended to the result of <code>toString</code> in
 * the future if more properties are added to the class.
 * 
 * @return a <code>String</code> representing the context settings.
 * @stable ICU 2.0
 */

// --public java.lang.String toString(){
function toString() {
	// --java.lang.String formstr=null;
	var formstr = null;
	// --int r=0;
	var r = 0;
	// --java.lang.String roundword=null;
	var roundword = null;
	{/* select */
		if (this.form == this.SCIENTIFIC)
			formstr = "SCIENTIFIC";
		else if (this.form == this.ENGINEERING)
			formstr = "ENGINEERING";
		else {
			formstr = "PLAIN";/* form=PLAIN */
		}
	}
	{
		var $1 = this.ROUNDS.length;
		r = 0;
		r: for (; $1 > 0; $1--, r++) {
			if (this.roundingMode == this.ROUNDS[r]) {
				roundword = this.ROUNDWORDS[r];
				break r;
			}
		}
	}/* r */
	return "digits=" + this.digits + " " + "form=" + formstr + " "
			+ "lostDigits=" + (this.lostDigits ? "1" : "0") + " "
			+ "roundingMode=" + roundword;
}

/* <sgml> Test whether round is valid. </sgml> */
// This could be made shared for use by BigDecimal for setScale.
// --private static boolean isValidRound(int testround){
function isValidRound(testround) {
	// --int r=0;
	var r = 0;
	{
		var $2 = this.ROUNDS.length;
		r = 0;
		r: for (; $2 > 0; $2--, r++) {
			if (testround == this.ROUNDS[r])
				return true;
		}
	}/* r */
	return false;
}
